#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Kernel 32 API Class Library
 *      Provides static, managed acccess to API calls in the kernel32 library.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "stdafx.h"
#include "BasicSafeHandle.h"
#include "MsDosDate.h"

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace Adaptive::Foundation;
using namespace Adaptive::Win32;

namespace Adaptive
{
	namespace Win32
	{
		/// <summary>
		/// Provides static, managed acccess to API calls in the kernel32 library.
		/// </summary>
		public ref class Kernel32 sealed
		{
		private:
			/*--------------------------------------------------------------------------------
			 * Constructor / Dispose / Destructor Methods
			 *------------------------------------------------------------------------------*/
			#pragma region Constructor / Dispose / Destructor Methods
			/// <summary>
			/// Initializes a new instance of the class.
			/// </summary>
			/// <remarks>
			/// This constructor is hidden to prevent instantiation.
			/// </remarks>
			Kernel32();
			#pragma endregion

			/*--------------------------------------------------------------------------------
			 * Private Static / Shared Methods / Functions
			 *------------------------------------------------------------------------------*/
			#pragma region Private Static / Shared Methods / Functions
			/// <summary>
			/// Opens an unmanaged process handle.
			/// </summary>
			/// <param name="processId">The ID of the process.</param>
			/// <returns>The HANDLE value, or NULL.</returns>
			static HANDLE InternalOpenProcessHandle(int processId);
			/// <summary>
			/// Opens an unmanaged thread handle.
			/// </summary>
			/// <param name="threadId">The ID of the thread.</param>
			/// <returns>The HANDLE value, or NULL.</returns>
			static HANDLE InternalOpenThreadHandle(int threadId);
			#pragma endregion

		public:
			/*--------------------------------------------------------------------------------
			 * Public Static / Shared Methods / Functions
			 *------------------------------------------------------------------------------*/
			#pragma region Public Static / Shared Methods / Functions
			/// <summary>
			/// Closes an open object handle.
			/// </summary>
			/// <remarks>
			/// This is used to safely close an operating system handle value.
			/// </remarks>
			/// <param name="handleToClose">An <see cref="IntPtr"/> represneting the handle to be closed.</param>
			static void CloseHandle(IntPtr handleToClose);
			/// <summary>
			/// Opens a file or device for read and write access.
			/// </summary>
			/// <remarks>
			/// This uses the system CreateFile() api for opening I/O to a file or device.
			/// </remarks>
			/// <param name="fileName">A string indicating the name of the file or name of the device to open.</param>
			/// <param name="mode">The desired file access mode.</param>
			/// <returns>
			/// If successful, returns a <see cref="BasicSafeHandle"/> instance containing the system handle to 
			/// the opened object instance; otherwise, returns <b>null</b>.
			/// </returns>
			static BasicSafeHandle^ CreateFileAccess(String^ fileName, FileMode mode);
			/// <summary>
			/// Opens a file or device for read and write access.
			/// </summary>
			/// <remarks>
			/// This uses the system CreateFile() api for opening I/O to a file or device.
			/// </remarks>
			/// <param name="fileName">A string indicating the name of the file or name of the device to open.</param>
			/// <param name="mode">The desired file access mode.</param>
			/// <param name="desiredAccess">A <see cref="DesiredAccessRights"/> enumeration indicating the desired access rights.</param>
			/// <returns>
			/// If successful, returns a <see cref="BasicSafeHandle"/> instance containing the system handle to 
			/// the opened object instance; otherwise, returns <b>null</b>.
			/// </returns>
			static BasicSafeHandle^ CreateFileAccess(String^ fileName, FileMode mode, DesiredAccessRights desiredAccess);
			/// <summary>
			/// Opens a file or device for read and write access.
			/// </summary>
			/// <remarks>
			/// This uses the system CreateFile() api for opening I/O to a file or device.
			/// </remarks>
			/// <param name="fileName">A string indicating the name of the file or name of the device to open.</param>
			/// <param name="mode">The desired file access mode.</param>
			/// <param name="desiredAccess">A <see cref="DesiredAccessRights"/> enumeration indicating the desired access rights.</param>
			/// <param name="shareMode">The desired file sharing mode.</param>
			/// <returns>
			/// If successful, returns a <see cref="BasicSafeHandle"/> instance containing the system handle to 
			/// the opened object instance; otherwise, returns <b>null</b>.
			/// </returns>
			static BasicSafeHandle^ CreateFileAccess(String^ fileName, FileMode mode, DesiredAccessRights desiredAccess, FileShare shareMode);
			/// <summary>
			/// Opens a file or device for read and write access.
			/// </summary>
			/// <remarks>
			/// This uses the system CreateFile() api for opening I/O to a file or device.
			/// </remarks>
			/// <param name="fileName">A string indicating the name of the file or name of the device to open.</param>
			/// <param name="mode">The desired file access mode.</param>
			/// <param name="desiredAccess">A <see cref="DesiredAccessRights"/> enumeration indicating the desired access rights.</param>
			/// <param name="shareMode">The desired file sharing mode.</param>
			/// <param name="fileOptions">A <see cref="FileAccessAttributeOptions"/> enumeration indicating the file attribute access
			/// desired.</param>
			/// <returns>
			/// If successful, returns a <see cref="BasicSafeHandle"/> instance containing the system handle to 
			/// the opened object instance; otherwise, returns <b>null</b>.
			/// </returns>
			static BasicSafeHandle^ CreateFileAccess(String^ fileName, FileMode mode, DesiredAccessRights desiredAccess, FileShare shareMode, 
										FileAccessAttributeOptions fileOptions);
			/// <summary>
			/// Duplicates an object handle.
			/// </summary>
			/// <remarks>
			/// The duplicate handle refers to the same object as the original handle.  Therefore, any changes to the object are reflected 
			/// through both handles.
			/// </remarks>
			/// <param name="sourceHandle">An <see cref="IntPtr"/> containing the handle to be duplicated.</param>
			/// <returns>
			/// A new <see cref="IntPtr"/> with the duplicated handle, or <see cref="IntPtr::Zero"/> if not successful.
			/// </returns>
			static IntPtr DuplicateHandle(IntPtr sourceHandle);
			/// <summary>
			/// Duplicates an object handle.
			/// </summary>
			/// <remarks>
			/// The duplicate handle refers to the same object as the original handle.  Therefore, any changes to the object are reflected 
			/// through both handles.
			/// </remarks>
			/// <param name="sourceHandle">An <see cref="IntPtr"/> containing the handle to be duplicated.</param>
			/// <param name="options">An <see cref="DuplicateHandleOptions"/> value specifying the access requested for the new handle.</param>
			/// <param name="inheritHandle">A value indicating whether to handle is inheritable.</param>
			/// <returns>
			/// A new <see cref="IntPtr"/> with the duplicated handle, or <see cref="IntPtr::Zero"/> if not successful.
			/// </returns>
			static IntPtr DuplicateHandle(IntPtr sourceHandle, DuplicateHandleOptions options, bool inheritHandle);
			/// <summary>
			/// Retrieves certain properties of an object handle.,
			/// </summary>
			/// <param name="itemHandle">An <see cref="IntPtr"/> containing the handle for which information is to
			/// be retrieved.</param>
			/// <returns>
			/// A <see cref="BitArray"/> instance containing the bit flags returned by the system.
			/// </returns>
			static BitArray^ GetHandleInformation(IntPtr itemHandle);
			/// <summary>
			/// Gets the name of the computer.
			/// </summary>
			/// <returns>
			/// The current computer name.
			/// </returns>
			static String^	ExtractComputerName();
			/// <summary>
			/// Converts the MS-DOS date value to a file-time value.
			/// </summary>
			/// <param name="dateValue">
			/// A <see cref="MsDosDate"/> instance containing the values.
			/// </param>
			/// <returns>
			/// The file-time value used to construct a system timne value.
			/// </returns>
			/// <exception cref="Win32Exception">
			/// Occurs if the underlying platform method fails (returns zero).
			/// </exception>
			static Int64 DosDateToFileTime(MsDosDate^ dateValue);
			/// <summary>
			/// Converts the specified file-time value to MS-DOS date and time values.
			/// </summary>
			/// <param name="fileTime">
			/// The file time value to be converted.
			/// </param>
			/// <returns>
			/// An <see cref="MsDosDate"/> structure containing the results.
			/// </returns>
			/// <exception cref="Win32Exception">
			/// Occurs if the underlying platform method fails (returns zero).
			/// </exception>
			static MsDosDate^ FileTimeToDosDate(Int64 fileTime);
			/// <summary>
			/// Converts the specified date/time value to MS-DOS date and time values.
			/// </summary>
			/// <param name="dateValue">
			/// The <see cref="DateTime"/> value to be converted.
			/// </param>
			/// <returns>
			/// An <see cref="MsDosDate"/> structure containing the results.
			/// </returns>
			/// <exception cref="Win32Exception">
			/// Occurs if the underlying platform method fails (returns zero).
			/// </exception>
			static MsDosDate^ DateTimeToDosDate(DateTime dateValue);
			/// <summary>
			/// Gets the handle to the current process.
			/// </summary>
			/// <returns>
			/// An <see cref="IntPtr"/> containing the handle to the current process.
			/// </returns>
			static IntPtr	GetCurrentProcessHandle();
			/// <summary>
			/// Gets the handle to the current process heap.
			/// </summary>
			/// <returns>
			/// An <see cref="IntPtr"/> containing the handle to the current process heap.
			/// </returns>
			static IntPtr	GetCurrentProcessHeap();
			/// <summary>
			/// Gets the ID of the current process.
			/// </summary>
			/// <returns>
			/// The ID of the current process.
			/// </returns>
			static int		GetCurrentProcId();
			/// <summary>
			/// Gets the version of Windows the specified process expects to execute on.
			/// </summary>
			/// <param name="processId">The ID of the process.</param>
			/// <returns>
			/// A <see cref="Version"/> instance containing the version numbers.
			/// </returns>
			static Version^ GetExpectedWindowsVersionForProcess(int processId);
			/// <summary>
			/// Gets the version of Windows the current process expects to execute on.
			/// </summary>
			/// <returns>
			/// A <see cref="Version"/> instance containing the version numbers.
			/// </returns>
			static Version^ GetExpectedWindowsVersionForCurrentProcess();
			/// <summary>
			/// Gets the handle to the desktop window.
			/// </summary>
			/// <returns>
			/// An <see cref="IntPtr"/> containing the handle to the desktop window.
			/// </returns>
			static IntPtr	GetHandleToDesktopWindow();
			/// <summary>
			/// Gets the path of the Windows system directory.
			/// </summary>
			/// <returns>
			/// The fully-qualified system path name.
			/// </returns>
			static String^	ExtractSystemDirectory();
			/// <summary>
			/// Gets the handle to the current thread.
			/// </summary>
			/// <returns>
			/// An <see cref="IntPtr"/> containing the handle to the current thread.
			/// </returns>
			static IntPtr	GetThisThreadHandle();
			/// <summary>
			/// Gets the ID of the current thread.
			/// </summary>
			/// <returns>
			/// The ID of the current thread.
			/// </returns>
			static int		GetThisThreadId();
			/// <summary>
			/// Gets the path of the Windows temp file directory.
			/// </summary>
			/// <returns>
			/// The fully-qualified temporary file path name.
			/// </returns>
			static String^	ExtractTempFileDirectory();
			/// <summary>
			/// Gets the name of the current user.
			/// </summary>
			/// <returns>
			/// The current user name.
			/// </returns>
			static String^	ExtractUserName();
			/// <summary>
			/// Gets the path of the Windows directory.
			/// </summary>
			/// <returns>
			/// The fully-qualified Windows path name.
			/// </returns>
			static String^	ExtractWindowsDirectory();
			/// <summary>
			/// Suspends the execution of the current thread for at least the specified interval.
			/// </summary>
			/// <remarks>
			/// This function causes a thread to relinquish the remainder of its time slice and become unrunnable for at least 
			/// the specified number of milliseconds, after which the thread is ready to run. In particular, if you specify 
			/// zero milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready 
			/// thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the specified 
			/// interval elapses.
			/// 
			/// Using this method will stop system messing processing for the thread.  This may cause system deadlock for threads
			/// which utilize system messages (such as windowing threads).
			///
			/// </remarks>
			/// <param name="milliseconds">Minimum time interval for which execution is to be suspended, in milliseconds.</param>
			static void		Sleep(int milliseconds);
			/// <summary>
			/// Sets certain properties of an object handle.
			/// </summary>
			/// <param name="itemHandle">An <see cref="IntPtr"/> containing the handle for which information is to
			/// be retrieved.</param>
			/// <param name="mask">An integer representing the bit flags to be set for the handle.</param>
			/// <param name="flags">A <see cref="SetHandleOptions"/> enumeration indicating the options for setting the handle flags.</param>
			/// <returns>
			/// <b>true</b> if the operation is successful; otherwise, returns <b>false</b>.
			/// </returns>
			static bool SetHandleInformation(IntPtr^ itemHandle, int mask, SetHandleOptions flags);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="proc">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetExitCodeForProcess(System::Diagnostics::Process^ proc);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetExitCodeForProcess(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="threadId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetExitCodeForThread(int threadId);
			/// <summary>
			/// 
			/// </summary>
			/// <returns>
			/// 
			/// </returns>
			static String^ GetProcessCommandLine();
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetGuiHandleCount(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetGuiHandleCount(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetGdiHandleCount(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetGdiHandleCount(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetUserHandleCount(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetUserHandleCount(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static IoCounters GetProcessIoCounters(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static IoCounters GetProcessIoCounters(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static ProcessTimes GetProcessProcessTimes(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static ProcessTimes GetProcessProcessTimes(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetProcessVersion(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static int GetProcessVersion(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static ProcessShutdownParameters GetProcessShutdownInfo(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static ProcessShutdownParameters GetProcessShutdownInfo(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="timing">
			/// 
			/// </param>
			/// <param name="noRetry">
			/// 
			/// </param>
			/// <returns>
			/// 
			/// </returns>
			static bool SetProcessShutdownInfo(ShutdownTiming timing, bool noRetry);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			static void TerminateProcess(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			static void TerminateProcess(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="threadId">
			/// 
			/// </param>
			static void TerminateThread(int threadId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			/// <param name="milliseconds">
			/// 
			/// </param>
			static void WaitForInputIdle(int processId, int milliseconds);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			/// <param name="milliseconds">
			/// 
			/// </param>
			static void WaitForInputIdle(System::Diagnostics::Process^ process, int milliseconds);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="process">
			/// 
			/// </param>
			static IntPtr OpenProcessHandle(System::Diagnostics::Process^ process);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="processId">
			/// 
			/// </param>
			static IntPtr OpenProcessHandle(int processId);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="milliseconds">
			/// 
			/// </param>
			static void SystemSleep(int milliseconds);
			/// <summary>
			/// 
			/// </summary>
			/// <param name="milliseconds">
			/// 
			/// </param>
			/// <param name="alertable">
			/// 
			/// </param>
			static void SystemSleep(int milliseconds, bool alertable);
			#pragma endregion

		};
	}
}
